﻿# -*- coding: utf-8 -*-
import os, sys, logging
parent_dir = os.path.abspath(os.path.dirname(__file__))
logging.info('parent_dir: %s', parent_dir)
if parent_dir not in sys.path:
    sys.path.insert(0, parent_dir)

# Remove the standard version of Django
if 'django' in sys.modules and sys.modules['django'].VERSION < (1, 2):
    for k in [k for k in sys.modules
              if k.startswith('django\.') or k == 'django']:
        del sys.modules[k]

from djangoappengine import boot
boot.setup_threading()
boot.setup_project()
boot.setup_logging()
boot.setup_env()

import django.core.handlers.wsgi
from google.appengine.ext.webapp import util
from django.conf import settings
os.environ.update(boot.env_ext)
#------
from djapp.models import *
from ComparableWave import *
from WaveCatalog import *


class DBController:
  def __init__(self):
    self.tags = []
    for lvl in Level.objects.all().order_by('level'): #sort Level.objects.
      self.tags.append({"category": lvl.name, "elements": lvl.tags})
    self.subtags = {}
    self.extended_tag = {}
    i = 0
    for cat in Category.objects.all():
      self.subtags[i] = {"tags": cat.tags, "wave_id": cat.wave_id, "header": cat.header}
      i += 1
    for tag in ExtendedTag.objects.all():
      self.extended_tag[tag.name] = set(tag.tags)
    
  def put(self, wavelet):
    """Puts wave to database."""
    wave = Wave(title = wavelet.title, wave_id = wavelet.wave_id, tags = wavelet.tags.serialize())
    try:
      wave.save()
    except: # Exception as exc:
      logging.error("Failed to put wave %s to db." % wavelet.wave_id)

    
  def delete(self, wave_id):
    """Deletes wave from database by its ID."""
    try:
      q = Wave.objects.filter(wave_id = wave_id) 
      for result in q:
        result.delete()
    except:
      logging.error("Failed to delete wave %s from db." % wave_id)
    
    
    
  def get_all(self):
    """Returns: dictionary of WaveCatalog objects for each user category."""
    subtags, general = {}, set()
    for ind in self.subtags.keys():
      if self.subtags[ind]["tags"]:
        subtags[ind] = self.subtags[ind]["tags"]    
      else:
        general.add(ind)
   
    waves = Wave.objects.all() 
    wave_catalog = {}
    for i in self.subtags.keys():
      wave_catalog[i] = WaveCatalog(self.tags) 
    for wave in waves:
      try:
        wave_lower_tags = set([q.lower() for q in wave.tags])
      except:
        wave_lower_tags = set([])
      new_wave_tags = wave_lower_tags.copy()
      index = set()
      for tag in wave_lower_tags:
        if tag in self.extended_tag:
          new_wave_tags = new_wave_tags.union(self.extended_tag[tag])
        for j in subtags.keys():
          if tag in subtags[j]:
            index.add(j)
      wave_lower_tags = new_wave_tags

      splited_wave_tags = [[]] #add wave to several level's tag 
      for lvl in range(len(self.tags)):
        lvl_length = len(splited_wave_tags) #length of repeated tags in previous lvl
        cur_length = 0
        for tag in self.tags[lvl]["elements"]:
          if tag.lower() in wave_lower_tags:
            for i in range(lvl_length):
              if cur_length > 0:
                splited_wave_tags.append(splited_wave_tags[i][:-1])
                splited_wave_tags[-1].append(tag)
              else:
                splited_wave_tags[i].append(tag)
            cur_length += 1

      for wave_tag in splited_wave_tags:
        for group in general:
          wave_catalog[group].put(ComparableWave(wave.wave_id, wave.title, wave_tag, self.tags)) #put wave in general category
        for group in index:
          wave_catalog[group].put(ComparableWave(wave.wave_id, wave.title, wave_tag, self.tags)) #put wave in each user category
    return wave_catalog
    